﻿namespace ImageProcessing.ImageProcessor
{
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using FourierTransform;
    using HighPass;
    using LowPass;
    using MathWorks.MATLAB.NET.Arrays;
    using MathWorks.MATLAB.NET.Utility;

    /// <summary>
    /// IMG_FourierClass Class
    /// </summary>
    public class IMG_FourierClass
    {
        /// <summary>
        /// Origional Image Buffer Red
        /// </summary>
        private double[,] origionalImageBufferRed;

        /// <summary>
        /// Origional Image Buffer Green
        /// </summary>
        private double[,] origionalImageBufferGreen;

        /// <summary>
        /// Origional Image Buffer blue
        /// </summary>
        private double[,] origionalImageBufferBlue;

        /// <summary>
        /// red magnitude
        /// </summary>
        private Entities.IMG_Image magnitudeRed;

        /// <summary>
        /// green magnitude
        /// </summary>
        private Entities.IMG_Image magnitudeGreen;

        /// <summary>
        /// blue magnitude
        /// </summary>
        private Entities.IMG_Image magnitudeBlue;

        /// <summary>
        /// red magnitude
        /// </summary>
        private double[,] magnitudeRedD;

        /// <summary>
        /// green magnitude
        /// </summary>
        private double[,] magnitudeGreenD;

        /// <summary>
        /// blue magnitude
        /// </summary>
        private double[,] magnitudeBlueD;

        /// <summary>
        /// original Image
        /// </summary>
        private Entities.IMG_Image origionalImg;

        /// <summary>
        ///  restored image
        /// </summary>
        private Entities.IMG_Image restoredImg;

        /// <summary>
        /// fourier instance
        /// </summary>
        private Fourier fourier = new Fourier();

        /// <summary>
        /// high pass instance
        /// </summary>
        private HighPass highPass = new HighPass();

        /// <summary>
        /// ideal low pass
        /// </summary>
        private LowPass.IdealLP idealLowPass = new IdealLP();

        /// <summary>
        /// butterworth instance
        /// </summary>
        private LowPass.ButterWorthLP butterWorthLowPass = new ButterWorthLP();

        /// <summary>
        /// gaussian low pass
        /// </summary>
        private LowPass.GaussianLP gaussianLowPass = new GaussianLP();

        /// <summary>
        /// Initializes a new instance of the <see cref="IMG_FourierClass"/> class.
        /// </summary>
        /// <param name="originalImage">The original image.</param>
        public IMG_FourierClass(Entities.IMG_Image originalImage)
        {
            try
            {
                this.origionalImg = originalImage;
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }

        /// <summary>
        /// Gets or sets the real red.
        /// </summary>
        /// <value>
        /// The real red.
        /// </value>
        public double[,] RealRed
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the real green.
        /// </summary>
        /// <value>
        /// The real green.
        /// </value>
        public double[,] RealGreen
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the real blue.
        /// </summary>
        /// <value>
        /// The real blue.
        /// </value>
        public double[,] RealBlue
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the imag red.
        /// </summary>
        /// <value>
        /// The imag red.
        /// </value>
        public double[,] ImagRed
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the imag green.
        /// </summary>
        /// <value>
        /// The imag green.
        /// </value>
        public double[,] ImagGreen
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the imag blue.
        /// </summary>
        /// <value>
        /// The imag blue.
        /// </value>
        public double[,] ImagBlue
        {
            get;
            set;
        }

        /// <summary>
        /// Gets the magnitude red.
        /// </summary>
        public Entities.IMG_Image MagnitudeRed
        {
            get { return this.magnitudeRed; }
        }

        /// <summary>
        /// Gets the magnitude green.
        /// </summary>
        public Entities.IMG_Image MagnitudeGreen
        {
            get { return this.magnitudeGreen; }
        }

        /// <summary>
        /// Gets the magnitude blue.
        /// </summary>
        public Entities.IMG_Image MagnitudeBlue
        {
            get { return this.magnitudeBlue; }
        }

        /// <summary>
        /// IMs the g_ calculate fourier.
        /// </summary>
        public void IMG_CalculateFourier()
        {
            try
            {
                this.magnitudeRed = new Entities.IMG_Image(this.origionalImg.Width, this.origionalImg.Height);
                this.magnitudeGreen = new Entities.IMG_Image(this.origionalImg.Width, this.origionalImg.Height);
                this.magnitudeBlue = new Entities.IMG_Image(this.origionalImg.Width, this.origionalImg.Height);

                this.magnitudeRedD = new double[this.origionalImg.Width, this.origionalImg.Height];
                this.magnitudeGreenD = new double[this.origionalImg.Width, this.origionalImg.Height];
                this.magnitudeBlueD = new double[this.origionalImg.Width, this.origionalImg.Height];

                this.origionalImageBufferRed = new double[this.origionalImg.Width, this.origionalImg.Height];
                this.origionalImageBufferGreen = new double[this.origionalImg.Width, this.origionalImg.Height];
                this.origionalImageBufferBlue = new double[this.origionalImg.Width, this.origionalImg.Height];

                this.RealRed = new double[this.origionalImg.Width, this.origionalImg.Height];
                this.RealGreen = new double[this.origionalImg.Width, this.origionalImg.Height];
                this.RealBlue = new double[this.origionalImg.Width, this.origionalImg.Height];

                this.ImagRed = new double[this.origionalImg.Width, this.origionalImg.Height];
                this.ImagGreen = new double[this.origionalImg.Width, this.origionalImg.Height];
                this.ImagBlue = new double[this.origionalImg.Width, this.origionalImg.Height];

                this.IMG_BufferToDoubleComponents();

                this.SetMangitudeValuesofColor(this.origionalImageBufferRed, 'R');
                this.SetMangitudeValuesofColor(this.origionalImageBufferGreen, 'G');
                this.SetMangitudeValuesofColor(this.origionalImageBufferBlue, 'B');

                for (int i = 0; i < this.origionalImageBufferRed.GetLength(0); i++)
                {
                    for (int j = 0; j < this.origionalImageBufferRed.GetLength(1); j++)
                    {
                        this.magnitudeRedD[i, j] = Math.Sqrt((this.RealRed[i, j] * this.RealRed[i, j]) + (this.ImagRed[i, j] * this.ImagRed[i, j]));
                        this.magnitudeGreenD[i, j] = Math.Sqrt((this.RealGreen[i, j] * this.RealGreen[i, j]) + (this.ImagGreen[i, j] * this.ImagGreen[i, j]));
                        this.magnitudeBlueD[i, j] = Math.Sqrt((this.RealBlue[i, j] * this.RealBlue[i, j]) + (this.ImagBlue[i, j] * this.ImagBlue[i, j]));
                    }
                }

                this.magnitudeRed = this.LogAndNormalize(this.magnitudeRedD, 'R');
                this.magnitudeGreen = this.LogAndNormalize(this.magnitudeGreenD, 'G');
                this.magnitudeBlue = this.LogAndNormalize(this.magnitudeBlueD, 'B');
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }

        /// <summary>
        /// Restores the image.
        /// </summary>
        /// <returns>restored image</returns>
        public Entities.IMG_Image RestoreImage()
        {
            try
            {
                this.RestoreOrigImageForEachColor(this.RealRed, this.ImagRed, 'R');
                this.RestoreOrigImageForEachColor(this.RealGreen, this.ImagGreen, 'G');
                this.RestoreOrigImageForEachColor(this.RealBlue, this.ImagBlue, 'B');
                this.restoredImg = new Entities.IMG_Image(this.origionalImageBufferRed.GetLength(0), this.origionalImageBufferRed.GetLength(1));
                for (int i = 0; i < this.origionalImageBufferRed.GetLength(0); i++)
                {
                    for (int j = 0; j < this.origionalImageBufferRed.GetLength(1); j++)
                    {
                        this.restoredImg[j, i] = new Entities.Pixel((int)this.origionalImageBufferRed[i, j], (int)this.origionalImageBufferGreen[i, j], (int)this.origionalImageBufferBlue[i, j]);
                    }
                }

                return this.restoredImg;
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }

        /// <summary>
        /// Applies the ideal high pass.
        /// </summary>
        /// <param name="d0">The d0.</param>
        /// <returns>edited image</returns>
        public Entities.IMG_Image ApplyIdealHighPass(double d0)
        {
            try
            {
                MWArray[] temp = new MWArray[2];
                temp = this.highPass.IdealHighPass(2, (MWNumericArray)this.RealRed, (MWNumericArray)this.ImagRed, (MWNumericArray)d0);
                MWArray temp_arr;
                temp_arr = this.fourier.RestoreToOrigionalImage(temp[0], temp[1]);
                this.origionalImageBufferRed = (double[,])temp_arr.ToArray();
                temp = this.highPass.IdealHighPass(2, (MWNumericArray)this.RealGreen, (MWNumericArray)this.ImagGreen, (MWNumericArray)d0);
                temp_arr = this.fourier.RestoreToOrigionalImage(temp[0], temp[1]);
                this.origionalImageBufferGreen = (double[,])temp_arr.ToArray();
                temp = this.highPass.IdealHighPass(2, (MWNumericArray)this.RealBlue, (MWNumericArray)this.ImagBlue, (MWNumericArray)d0);
                temp_arr = this.fourier.RestoreToOrigionalImage(temp[0], temp[1]);
                this.origionalImageBufferBlue = (double[,])temp_arr.ToArray();
                this.restoredImg = this.NormalizeImage(this.origionalImageBufferRed, this.origionalImageBufferGreen, this.origionalImageBufferBlue);
                return this.restoredImg;
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }

        /// <summary>
        /// Applies the ideal low pass.
        /// </summary>
        /// <param name="d0">The d0.</param>
        /// <returns>edited image</returns>
        public Entities.IMG_Image ApplyIdealLowPass(double d0)
        {
            try
            {
                MWArray[] temp = new MWArray[2];
                temp = this.idealLowPass.ILPF(2, (MWNumericArray)this.RealRed, (MWNumericArray)this.ImagRed, (MWNumericArray)d0);
                MWArray temp_arr;
                temp_arr = this.fourier.RestoreToOrigionalImage(temp[0], temp[1]);
                this.origionalImageBufferRed = (double[,])temp_arr.ToArray();
                temp = this.idealLowPass.ILPF(2, (MWNumericArray)this.RealGreen, (MWNumericArray)this.ImagGreen, (MWNumericArray)d0);
                temp_arr = this.fourier.RestoreToOrigionalImage(temp[0], temp[1]);
                this.origionalImageBufferGreen = (double[,])temp_arr.ToArray();
                temp = this.idealLowPass.ILPF(2, (MWNumericArray)this.RealBlue, (MWNumericArray)this.ImagBlue, (MWNumericArray)d0);
                temp_arr = this.fourier.RestoreToOrigionalImage(temp[0], temp[1]);
                this.origionalImageBufferBlue = (double[,])temp_arr.ToArray();
                this.restoredImg = this.CutOff(this.origionalImageBufferRed, this.origionalImageBufferGreen, this.origionalImageBufferBlue);
                return this.restoredImg;
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }

        /// <summary>
        /// Applies the gaussian high pass.
        /// </summary>
        /// <param name="d0">The d0.</param>
        /// <returns>the edited image</returns>
        public Entities.IMG_Image ApplyGaussianHighPass(double d0)
        {
            try
            {
                MWArray[] temp = new MWArray[2];
                temp = this.highPass.GaussianHighPass(2, (MWNumericArray)this.RealRed, (MWNumericArray)this.ImagRed, (MWNumericArray)d0);
                MWArray temp_arr;
                temp_arr = this.fourier.RestoreToOrigionalImage(temp[0], temp[1]);
                this.origionalImageBufferRed = (double[,])temp_arr.ToArray();
                temp = this.highPass.GaussianHighPass(2, (MWNumericArray)this.RealGreen, (MWNumericArray)this.ImagGreen, (MWNumericArray)d0);
                temp_arr = this.fourier.RestoreToOrigionalImage(temp[0], temp[1]);
                this.origionalImageBufferGreen = (double[,])temp_arr.ToArray();
                temp = this.highPass.GaussianHighPass(2, (MWNumericArray)this.RealBlue, (MWNumericArray)this.ImagBlue, (MWNumericArray)d0);
                temp_arr = this.fourier.RestoreToOrigionalImage(temp[0], temp[1]);
                this.origionalImageBufferBlue = (double[,])temp_arr.ToArray();
                this.restoredImg = this.NormalizeImage(this.origionalImageBufferRed, this.origionalImageBufferGreen, this.origionalImageBufferBlue);
                return this.restoredImg;
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }

        /// <summary>
        /// Applies the gaussian low pass.
        /// </summary>
        /// <param name="d0">The d0.</param>
        /// <returns>the edited image</returns>
        public Entities.IMG_Image ApplyGaussianLowPass(double d0)
        {
            try
            {
                MWArray[] temp = new MWArray[2];
                temp = this.gaussianLowPass.GLPF(2, (MWNumericArray)this.RealRed, (MWNumericArray)this.ImagRed, (MWNumericArray)d0);
                MWArray temp_arr;
                temp_arr = this.fourier.RestoreToOrigionalImage(temp[0], temp[1]);
                this.origionalImageBufferRed = (double[,])temp_arr.ToArray();
                temp = this.gaussianLowPass.GLPF(2, (MWNumericArray)this.RealGreen, (MWNumericArray)this.ImagGreen, (MWNumericArray)d0);
                temp_arr = this.fourier.RestoreToOrigionalImage(temp[0], temp[1]);
                this.origionalImageBufferGreen = (double[,])temp_arr.ToArray();
                temp = this.gaussianLowPass.GLPF(2, (MWNumericArray)this.RealBlue, (MWNumericArray)this.ImagBlue, (MWNumericArray)d0);
                temp_arr = this.fourier.RestoreToOrigionalImage(temp[0], temp[1]);
                this.origionalImageBufferBlue = (double[,])temp_arr.ToArray();
                this.restoredImg = this.CutOff(this.origionalImageBufferRed, this.origionalImageBufferGreen, this.origionalImageBufferBlue);
                return this.restoredImg;
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }

        /// <summary>
        /// Applies the butter worth high pass.
        /// </summary>
        /// <param name="d0">The d0.</param>
        /// <param name="n">The N.</param>
        /// <returns>the edited image</returns>
        public Entities.IMG_Image ApplyButterWorthHighPass(double d0, double n)
        {
            try
            {
                MWArray[] temp = new MWArray[2];
                temp = this.highPass.ButterworthHighPass(2, n, (MWNumericArray)this.RealRed, (MWNumericArray)this.ImagRed, (MWNumericArray)d0);
                MWArray temp_arr;
                temp_arr = this.fourier.RestoreToOrigionalImage(temp[0], temp[1]);
                this.origionalImageBufferRed = (double[,])temp_arr.ToArray();
                temp = this.highPass.ButterworthHighPass(2, n, (MWNumericArray)this.RealGreen, (MWNumericArray)this.ImagGreen, (MWNumericArray)d0);
                temp_arr = this.fourier.RestoreToOrigionalImage(temp[0], temp[1]);
                this.origionalImageBufferGreen = (double[,])temp_arr.ToArray();
                temp = this.highPass.ButterworthHighPass(2, n, (MWNumericArray)this.RealBlue, (MWNumericArray)this.ImagBlue, (MWNumericArray)d0);
                temp_arr = this.fourier.RestoreToOrigionalImage(temp[0], temp[1]);
                this.origionalImageBufferBlue = (double[,])temp_arr.ToArray();
                this.restoredImg = this.NormalizeImage(this.origionalImageBufferRed, this.origionalImageBufferGreen, this.origionalImageBufferBlue);
                return this.restoredImg;
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }

        /// <summary>
        /// Applies the butter worth low pass.
        /// </summary>
        /// <param name="d0">The d0.</param>
        /// <param name="n">The N.</param>
        /// <returns>the edited image</returns>
        public Entities.IMG_Image ApplyButterWorthLowPass(double d0, double n)
        {
            try
            {
                MWArray[] temp = new MWArray[2];
                temp = this.butterWorthLowPass.BLPF(2, (MWNumericArray)this.RealRed, (MWNumericArray)this.ImagRed, n, (MWNumericArray)d0);
                MWArray temp_arr;
                temp_arr = this.fourier.RestoreToOrigionalImage(temp[0], temp[1]);
                this.origionalImageBufferRed = (double[,])temp_arr.ToArray();
                temp = this.butterWorthLowPass.BLPF(2, (MWNumericArray)this.RealGreen, (MWNumericArray)this.ImagGreen, n, (MWNumericArray)d0);
                temp_arr = this.fourier.RestoreToOrigionalImage(temp[0], temp[1]);
                this.origionalImageBufferGreen = (double[,])temp_arr.ToArray();
                temp = this.butterWorthLowPass.BLPF(2, (MWNumericArray)this.RealBlue, (MWNumericArray)this.ImagBlue, n, (MWNumericArray)d0);
                temp_arr = this.fourier.RestoreToOrigionalImage(temp[0], temp[1]);
                this.origionalImageBufferBlue = (double[,])temp_arr.ToArray();
                this.restoredImg = this.CutOff(this.origionalImageBufferRed, this.origionalImageBufferGreen, this.origionalImageBufferBlue);
                return this.restoredImg;
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }

        /// <summary>
        /// IMs the g_ buffer to double components.
        /// </summary>
        private void IMG_BufferToDoubleComponents()
        {
            try
            {
                Entities.Pixel img_PixelColor;
                for (int i = 0; i < this.origionalImg.Height; i++)
                {
                    for (int j = 0; j < this.origionalImg.Width; j++)
                    {
                        img_PixelColor = new Entities.Pixel(this.origionalImg[i, j].Red, this.origionalImg[i, j].Green, this.origionalImg[i, j].Blue);
                        this.origionalImageBufferRed[j, i] = Convert.ToDouble(img_PixelColor.Red);
                        this.origionalImageBufferGreen[j, i] = Convert.ToDouble(img_PixelColor.Green);
                        this.origionalImageBufferBlue[j, i] = Convert.ToDouble(img_PixelColor.Blue);
                    }
                }
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }

        /// <summary>
        /// Normalizes the image.
        /// </summary>
        /// <param name="imgR">The img R.</param>
        /// <param name="imgG">The img G.</param>
        /// <param name="imgB">The img B.</param>
        /// <returns>normalized img</returns>
        private Entities.IMG_Image NormalizeImage(double[,] imgR, double[,] imgG, double[,] imgB)
        {
            try
            {
                int w = imgR.GetLength(0);
                int h = imgR.GetLength(1);
                double minR = double.MaxValue;
                double maxR = double.MinValue;
                double minG = double.MaxValue;
                double maxG = double.MinValue;
                double minB = double.MaxValue;
                double maxB = double.MinValue;
                Entities.IMG_Image retImg = new Entities.IMG_Image(w, h);
                for (int i = 0; i < w; i++)
                {
                    for (int j = 0; j < h; j++)
                    {
                        minR = minR < imgR[i, j] ? minR : imgR[i, j];
                        maxR = maxR > imgR[i, j] ? maxR : imgR[i, j];
                        minG = minG < imgG[i, j] ? minG : imgG[i, j];
                        maxG = maxG > imgG[i, j] ? maxG : imgG[i, j];
                        minB = minB < imgB[i, j] ? minB : imgB[i, j];
                        maxB = maxB > imgB[i, j] ? maxB : imgB[i, j];
                    }
                }

                for (int i = 0; i < w; i++)
                {
                    for (int j = 0; j < h; j++)
                    {
                        imgR[i, j] = (((imgR[i, j] - minR) / (maxR - minR)) * 255) > 0 ? (((imgR[i, j] - minR) / (maxR - minR)) * 255) : 0;
                        imgG[i, j] = ((imgG[i, j] - minG) / (maxG - minG)) * 255 > 0 ? (((imgG[i, j] - minG) / (maxG - minG)) * 255) : 0;
                        imgB[i, j] = ((imgB[i, j] - minB) / (maxB - minB)) * 255 > 0 ? (((imgB[i, j] - minB) / (maxB - minB)) * 255) : 0;
                        retImg[j, i] = new Entities.Pixel((int)imgR[i, j], (int)imgG[i, j], (int)imgB[i, j]);
                    }
                }

                return retImg;
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }

        /// <summary>
        /// Cutoff the image.
        /// </summary>
        /// <param name="imgR">The img R.</param>
        /// <param name="imgG">The img G.</param>
        /// <param name="imgB">The img B.</param>
        /// <returns>the ctoff image</returns>
        private Entities.IMG_Image CutOff(double[,] imgR, double[,] imgG, double[,] imgB)
        {
            try
            {
                int w = imgR.GetLength(0);
                int h = imgR.GetLength(1);
                Entities.IMG_Image retImg = new Entities.IMG_Image(w, h);
                for (int i = 0; i < w; i++)
                {
                    for (int j = 0; j < h; j++)
                    {
                        imgR[i, j] = imgR[i, j] < 0 ? 0 : imgR[i, j];
                        imgR[i, j] = imgR[i, j] > 255 ? 255 : imgR[i, j];
                        imgG[i, j] = imgG[i, j] < 0 ? 0 : imgG[i, j];
                        imgG[i, j] = imgG[i, j] > 255 ? 255 : imgG[i, j];
                        imgB[i, j] = imgB[i, j] < 0 ? 0 : imgB[i, j];
                        imgB[i, j] = imgB[i, j] > 255 ? 255 : imgB[i, j];
                        retImg[j, i] = new Entities.Pixel((int)imgR[i, j], (int)imgG[i, j], (int)imgB[i, j]);
                    }
                }

                return retImg;
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }

        /// <summary>
        /// Sets the color of the mangitude valuesof.
        /// </summary>
        /// <param name="org_Buffer">The org_ buffer.</param>
        /// <param name="c">The c.</param>
        private void SetMangitudeValuesofColor(double[,] org_Buffer, char c)
        {
            try
            {
                MWArray[] temp_arr = new MWArray[2];
                temp_arr = this.fourier.ConvertToFrequencyDomain(2, (MWNumericArray)org_Buffer);
                if (c == 'R')
                {
                    this.RealRed = (double[,])temp_arr[0].ToArray();
                    this.ImagRed = (double[,])temp_arr[1].ToArray();
                }
                else if (c == 'G')
                {
                    this.RealGreen = (double[,])temp_arr[0].ToArray();
                    this.ImagGreen = (double[,])temp_arr[1].ToArray();
                }
                else
                {
                    this.RealBlue = (double[,])temp_arr[0].ToArray();
                    this.ImagBlue = (double[,])temp_arr[1].ToArray();
                }
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }

        /// <summary>
        /// Restores the color of the orig image for each.
        /// </summary>
        /// <param name="real_buff">The real_buff.</param>
        /// <param name="imag_buff">The imag_buff.</param>
        /// <param name="c">The c.</param>
        private void RestoreOrigImageForEachColor(double[,] real_buff, double[,] imag_buff, char c)
        {
            try
            {
                MWArray temp_arr;
                temp_arr = this.fourier.RestoreToOrigionalImage((MWNumericArray)real_buff, (MWNumericArray)imag_buff);
                if (c == 'R')
                {
                    this.origionalImageBufferRed = (double[,])temp_arr.ToArray();
                }
                else if (c == 'G')
                {
                    this.origionalImageBufferGreen = (double[,])temp_arr.ToArray();
                }
                else
                {
                    this.origionalImageBufferBlue = (double[,])temp_arr.ToArray();
                }
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }

        /// <summary>
        /// Logs the and normalize.
        /// </summary>
        /// <param name="img">The img.</param>
        /// <param name="color">The color.</param>
        /// <returns>niormalized logged image</returns>
        private Entities.IMG_Image LogAndNormalize(double[,] img, char color)
        {
            try
            {
                int w = img.GetLength(0);
                int h = img.GetLength(1);
                double min = double.MaxValue;
                double max = double.MinValue;

                Entities.IMG_Image retImg = new Entities.IMG_Image(w, h);

                for (int i = 0; i < w; i++)
                {
                    for (int j = 0; j < h; j++)
                    {
                        img[i, j] = Math.Log(img[i, j] + 1);
                        min = min < img[i, j] ? min : img[i, j];
                        max = max > img[i, j] ? max : img[i, j];
                    }
                }

                if (min == max && min == 0)
                {
                    return retImg;
                }

                int clr;
                for (int i = 0; i < w; i++)
                {
                    for (int j = 0; j < h; j++)
                    {
                        img[i, j] = ((img[i, j] - min) / (max - min)) * 255;
                        clr = (int)img[i, j];
                        switch (color)
                        {
                            case 'R':
                                retImg[j, i] = new Entities.Pixel(clr, 0, 0);
                                break;
                            case 'G':
                                retImg[j, i] = new Entities.Pixel(0, clr, 0);
                                break;
                            case 'B':
                                retImg[j, i] = new Entities.Pixel(0, 0, clr);
                                break;
                        }
                    }
                }

                return retImg;
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }
    }
}
